#include "MyCanvas.h"

MyCanvas::MyCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size) :
    QSFMLCanvas(Parent, Position, Size)
{
}

void MyCanvas::onInit()
{
    srand(time(NULL));

    ///Creation de la grille d'hexagones

    Hexagone **hTab;

    hTab=new Hexagone*[TAB_LENGTH];
    for (int i(0);i<TAB_LENGTH;i++)
    {
        hTab[i]=new Hexagone[TAB_HEIGHT];
    }

    for(int j(0);j<TAB_HEIGHT;j++)
    {
        if(j%2==0)
        {
            for(int i(0);i<TAB_LENGTH;i++)
            {
                hTab[i][j]=Hexagone((i*H_LENGTH)+5,(j*((H_HEIGHT/4)*3))+5);
            }
        }
        else
        {
            for(int i(0);i<TAB_LENGTH;i++)
            {
                hTab[i][j]=Hexagone(((i*H_LENGTH)+(H_LENGTH/2))+5,((j*((H_HEIGHT/4)*3)))+5);
            }
        }
    }

    /****************************/

    ///Creation d'un tableau repertoriant les centres de territoire choisis aleatoirement

    sf::Vector2i* centres;

    centres=new sf::Vector2i[TERR];

    for(int i(0);i<TERR;i++)
    {
        int a(0);
        sf::Vector2i v((rand()%TAB_LENGTH),(rand()%TAB_HEIGHT));
        while(a<i)
        {
            float fx((hTab[v.x][v.y].getPoint(0).x)-(hTab[centres[a].x][centres[a].y].getPoint(0).x)),fy((hTab[v.x][v.y].getPoint(0).y)-(hTab[centres[a].x][centres[a].y].getPoint(0).y));
            if(((fx*fx)+(fy*fy))<PORTEE)
            {
                a=0;
                v.x=rand()%TAB_LENGTH;
                v.y=rand()%TAB_HEIGHT;
            }
            else
            {
                a++;
            }
        }
        centres[i]=v;
    }

    /****************************/

    ///Completion des territoires

    std::vector<Hexagone>* restes;

    restes=new std::vector<Hexagone>[TERR];

    for(int j(0);j<TAB_HEIGHT;j++)
    {
        for(int i(0);i<TAB_LENGTH;i++)
        {
            int a(-1);
            float dist(PORTEE);

            for(int k(0);k<TERR;k++)
            {
                float fx((hTab[i][j].getPoint(0).x)-(hTab[centres[k].x][centres[k].y].getPoint(0).x)),fy((hTab[i][j].getPoint(0).y)-(hTab[centres[k].x][centres[k].y].getPoint(0).y));
                float temp((fx*fx)+(fy*fy));
                if(temp<dist)
                {
                    dist=temp;
                    a=k;
                }
            }
            if(a>=0)
            {
                if (pays[a].surface.getPointCount()==0)
                {
                    pays[a].surface=hTab[i][j];
                }
                else
                {
                    pays[a].ajouterHexagone(hTab[i][j],restes[a]);
                }
            }
        }
    }
    for (int i(0);i<TERR;i++)
    {
        int taille(restes[i].size());
        for (int j(0);j<taille;j++)
        {
            Hexagone h(restes[i].back());
            restes[i].pop_back();
            pays[i].ajouterHexagone(h,restes[i]);
        }
    }

    ///Determination des territoires voisins de chaque territoire

    std::vector<int>** grilleVoisins;

    int lg((TAB_LENGTH*H_LENGTH)+(H_LENGTH/2)+6), hg((TAB_HEIGHT*((H_HEIGHT/4)*3))+6);

    grilleVoisins=new std::vector<int>*[lg];
    for (int i(0);i<lg;i++)
    {
        grilleVoisins[i]=new std::vector<int>[hg];
    }

    for (int i(0);i<TERR;i++)
    {
        int nbPoints(pays[i].surface.getPointCount());
        for (int k(0);k<nbPoints;k++)
        {
            grilleVoisins[int(pays[i].surface.getPoint(k).x)][int(pays[i].surface.getPoint(k).y)].push_back(i);
        }
    }

    bool** bilanVoisins;

    bilanVoisins=new bool*[TERR];
    for (int i(0);i<TERR;i++)
    {
        bilanVoisins[i]=new bool[TERR];
    }

    for (int i(0);i<TERR;i++)
    {
        for (int j(0);j<TERR;j++)
        {
            bilanVoisins[i][j]=false;
        }
    }

    for (int i(0);i<TERR;i++)
    {
        int nbPoints(pays[i].surface.getPointCount());
        for (int k(0);k<nbPoints;k++)
        {
            std::vector<int> vv(grilleVoisins[int(pays[i].surface.getPoint(k).x)][int(pays[i].surface.getPoint(k).y)]);
            int taille(vv.size());
            for (int l(0);l<taille;l++)
            {
                int a(vv[l]);
                if (i!=a)
                {
                    bilanVoisins[i][a]=true;
                }
            }
        }
    }

    for (int i(0);i<TERR;i++)
    {
        for (int j(0);j<TERR;j++)
        {
            if (bilanVoisins[i][j])
            {
                pays[i].voisins.push_back(&(pays[j]));
            }
        }
    }

    /****************************/

    ///Suppression des structures temporaires

    for (int i(0);i<TERR;i++)
    {
        delete[] bilanVoisins[i];
    }
    delete[] bilanVoisins;

    for (int i(0);i<lg;i++)
    {
        delete[] grilleVoisins[i];
    }
    delete[] grilleVoisins;

    delete[] restes;

    delete[] centres;

    for (int i(0);i<TAB_LENGTH;i++)
    {
        delete[] hTab[i];
    }
    delete[] hTab;

    /****************************/

    ///Creation des frontieres

    for (int i(0);i<TERR;i++)
    {
        pays[i].creerFrontiere();
    }

    /****************************/

    for (int i(0);i<TERR;i++)
    {
        pays[i].surface.setFillColor(sf::Color(i*50,250-(i*50),i*50));
        pays[i].surface.setOutlineThickness(3);
        pays[i].surface.setOutlineColor(sf::Color::Black);
    }

    clock.restart();
}

void MyCanvas::onUpdate()
{
    clear(sf::Color::White);

    for (int i(0);i<TERR;i++)
    {
        draw(pays[i].surface);
    }
/*
    if (sf::Mouse::isButtonPressed(sf::Mouse::Left) && isIn())
    {
        mySprite.setPosition(sf::Mouse::getPosition().x - mapToGlobal(QPoint(0, 0)).x(), sf::Mouse::getPosition().y - mapToGlobal(QPoint(0, 0)).y());
    }*/

    clock.restart();
}

bool MyCanvas::isIn()
{
    return this->underMouse();
}
